home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Tele / C / Comet2.1.3.cpt / Comet / h19.c < prev    next >
Text File  |  1991-10-17  |  15KB  |  715 lines

  1. /*
  2.     Copyright Cornell University 1986.  All rights are reserved.
  3. */
  4.  
  5. #include    <em.h>
  6.  
  7. #include    <h19.h>
  8.  
  9.                         
  10. extern short usedsdraw;            /* set through emprep() */
  11. extern short emupdwait;            /* set through emprep() */
  12.  
  13.  
  14. /* 
  15.  * The h19 emulator routine, which interprets escape commands and other 
  16.  * control codes like a Heath-19 (quite similar to DEC VT-52)
  17.  *
  18.  */
  19.  
  20. h19(thechar)
  21. char thechar;
  22. {
  23.     h19str(&thechar, 1);
  24. }
  25.  
  26.  
  27. h19str(strp, ccount)
  28. register unsigned char * strp;
  29. int ccount;
  30. {
  31.     register unsigned char * endp = strp + ccount;
  32.     register unsigned char thechar;
  33.     int count;
  34.     
  35.     emprep();
  36.     if (usedsdraw) {
  37.         emdp->inselection = chkinvert();
  38.         setascattr_ds(attrib, emdp->inselection);
  39.  
  40.     }
  41.  
  42.     while (strp < endp) {
  43.         thechar = *strp++;             /*  & 0x7f -- assumed */
  44.         if (mode == NORMMODE) {
  45.             /* NORMMODE interpreted here to avoid switch overhead */
  46.             /* draw character if alphanumeric */
  47.             if (emdp->emliteral || (thechar >= 0x20 && thechar != 0x7f)) {
  48. #ifdef BETTERLITERAL
  49.                 if (emdp->emliteral) {
  50.                     /* remap control chars so they are not interpreted */
  51.                     if (thechar == CR) {
  52.                         thechar = 0x86;
  53.                     }
  54.                     else if (thechar == HTAB) {
  55.                         thechar = 0x84;
  56.                     }
  57.                 }
  58. #endif
  59.                 if (inserton) {
  60.                     ins_char();
  61.                 }
  62.                 *charp = thechar;
  63.                 *(charp + emdp->screensize) = attrib;
  64.                 if (emdp->matchinput) {
  65.                     /* we're trying to match input characters */
  66.                     if (matchtoken(thechar))
  67.                         resumetokens(emdp); 
  68.                 }
  69. #ifdef FASTDRAW
  70.                 if (usedsdraw) {
  71.                     /* we're using direct-to-screen drawing */
  72.                     if (modflg) {
  73.                         emrefresh(emwindow, TRUE);
  74.                     }    
  75.                     if (emdp->selrectvis) {
  76.                         if (emdp->inselection != chkinvert()) {
  77.                             if (emdp->inselection)
  78.                                 emdp->inselection = FALSE;
  79.                             else
  80.                                 emdp->inselection = TRUE;
  81.                             setascattr_ds(attrib, emdp->inselection);
  82.                         }
  83.                     }
  84.                     zapchar(thechar);
  85.                     clrflg &= ~modmask[ypos];        /* reset clear flag */
  86.                 }
  87.                 else {
  88.                     /* for quickdraw, draw when finished updating map
  89.                         if (inserton || ccount == 1)
  90.                             ch_draw_qd(thechar);
  91.                         else
  92.                      */
  93.                     modflg |= modmask[ypos];
  94.                 }
  95. #else
  96.                 modflg |= modmask[ypos];
  97. #endif
  98.                 /* adjust cursor position */
  99.                 if (xpos < lastcol) {
  100.                     ++xpos;
  101.                     ++charp;
  102.                 }
  103.                 else if (wrap_around) {
  104.                     charp -= xpos;
  105.                     xpos = 0;
  106.                     if (ypos < emdp->lastrow) {
  107.                         charp += linelength;
  108.                         ++ypos;
  109.                     }
  110.                     else {
  111.                         (*emdp->scrollup)();
  112.                     }
  113.                 }
  114.                 continue;
  115.             }
  116.             else {
  117.                 /* an ascii control character... */
  118.                 switch(thechar) {
  119.                     case 0x07: {
  120.                         /* BELL */
  121.                         if (!emdp->emdisable)
  122.                             beep();
  123.                         break;
  124.                     }
  125.                     case 0x08: {
  126.                         /* BS */
  127.                         if (xpos) {
  128.                             --xpos;
  129.                             --charp;
  130.                         }
  131.                         break;
  132.                     }
  133.                     case 0x09: {
  134.                         /* HTAB */
  135.                         short shift;
  136.  
  137.                         if (xpos < lastcol - TABSIZE) {
  138.                             shift = ((xpos + TABSIZE) & ~7) - xpos;
  139.                             xpos += shift;
  140.                             charp += shift;
  141.                         }
  142.                         else if (xpos < lastcol) {
  143.                             ++xpos;
  144.                             ++charp;
  145.                         }
  146.                         break;
  147.                     }
  148.                     case 0x0c: {
  149.                         /* FF */
  150.                         if (xpos < lastcol) {
  151.                             ++xpos;
  152.                             ++charp;
  153.                         }
  154.                         else {
  155.                             charp -= xpos;
  156.                             xpos = 0;
  157.                             if (ypos < emdp->lastrow) {
  158.                                 ++ypos;
  159.                                 charp += linelength;
  160.                             }
  161.                             else {
  162.                                 ypos = 0;
  163.                                 charp = emdp->charr;
  164.                             }
  165.                         }
  166.                         break;
  167.                     }
  168.                     case 0x0a: {
  169.                         /* LF */
  170.                         /* NEW draw line if QD? */
  171.                         if (ypos < emdp->lastrow) {
  172.                             ++ypos;
  173.                             charp += linelength;
  174.                         }
  175.                         else {
  176.                             (*emdp->scrollup)();
  177.                         }
  178.                         break;
  179.                     }
  180.                     case 0x0d: {
  181.                         /* CR */
  182.                         charp -= xpos;
  183.                         xpos = 0;
  184.                         break;
  185.                     }
  186.                     case 0x1a: {
  187.                         /* SUB */
  188.                         if (emdp->selrectvis || bkrd_act || emupdwait) {
  189.                             /* must redraw through upd */
  190.                             modflg = SCRALLMOD;
  191.                         }
  192.                         else {
  193.                             clearrect(&emdp->bigrect);
  194.                             clrflg = SCRALLMOD;
  195.                         }
  196.                         if (!emdp->ibm_keymode)
  197.                             savescreen();
  198.                             
  199.                         c19_blankmap(&emdp->charr[0]);
  200.                         xpos = ypos = 0;
  201.                         charp = emdp->charr;
  202.                         break;
  203.                     }
  204.                     case 0x1b: {
  205.                         /* ESC */
  206.                         mode = ESCMODE;
  207.                         break;
  208.                     }
  209.                     case 0x1e: {
  210.                         /* RS */
  211.                         charp = emdp->charr;
  212.                         xpos = ypos = 0;
  213.                         break;
  214.                     }
  215.                 }
  216.                 continue;
  217.             }
  218.         }    
  219.  
  220.         /* else interpret character according to proper mode */
  221.         if (mode == ESCMODE) {
  222.             switch(thechar) {
  223.                 case ESC: {
  224.                     /* 2 Escape characters: go into c19 file transfer mode */
  225.                     mode = CFTMODE;
  226.                     continue;
  227.                 }
  228.                 case 'A': {
  229.                     /* cursor up */
  230.                     if (ypos > 0) {
  231.                         ypos--;
  232.                         charp -= linelength;
  233.                     }
  234.                     break;
  235.                 }
  236.                 case 'B': {
  237.                     /* cursor down */
  238.                     if (ypos < emdp->lastrow) {
  239.                         ++ypos;
  240.                         charp += linelength;
  241.                     }
  242.                     break;
  243.                 }
  244.                 case 'C': {
  245.                     /* cursor right */
  246.                     if (xpos < lastcol) {
  247.                         ++xpos;
  248.                         ++charp;
  249.                     }
  250.                     break;
  251.                 }
  252.                 case 'D': {
  253.                     /* cursor left */
  254.                     if (xpos > 0) {
  255.                         --xpos;
  256.                         --charp;
  257.                     }
  258.                     break;
  259.                 }
  260.                 case 'E': {
  261.                     /* reset:  clear screen */
  262.                     if (!emdp->ibm_keymode)
  263.                         savescreen();
  264.             
  265.                     h19reset();
  266. #ifdef FASTDRAW
  267.                     setascattr_ds(attrib, emdp->inselection);
  268. #endif
  269.  
  270.                     break;
  271.                 }
  272.                 /* TODO support 7171 modes, invis, highlight, protect */
  273.                 case 'U':    /* 7171 highlight unprotect */
  274.                 case 'W':    /* 7171 highlight protect */
  275.                 case 'F': {
  276.                     attrib |= BOLD;
  277. #ifdef FASTDRAW
  278.                     setascattr_ds(attrib, emdp->inselection);
  279. #endif
  280.                     break;
  281.                 }
  282.                 case 'S':    /* 7171 invisible */
  283.                 case 'T':    /* 7171 normal unprotect */
  284.                 case 'V':    /* 7171 normal protect */
  285.                 case 'G': {
  286.                     /* end alt char set */
  287.                     attrib = NORMFONT;
  288. #ifdef FASTDRAW
  289.                     setascattr_ds(attrib, emdp->inselection);
  290. #endif
  291.                     break;
  292.                 }
  293.                 case 'H': {
  294.                     /* home */
  295.                     xpos = 0;
  296.                     ypos = 0;
  297.                     charp = emdp->charr;
  298.                     break;
  299.                 }
  300.                 case 'I': {
  301.                     /* reverse index */
  302.                     if (ypos == 0)
  303.                         ins_lin(0);
  304.                     else {
  305.                         --ypos;
  306.                         charp -= linelength;
  307.                     }
  308.                     break;
  309.                 }
  310.                 case 'J': {
  311.                     /* clear to end of screen */
  312.                     if (emdp->selrectvis || bkrd_act || emupdwait) {
  313.                         /* must redraw through upd */
  314.                         for (count = ypos; count <= emdp->lastrow; count++)
  315.                             modflg |= modmask[count];
  316.                     }
  317.                     else {
  318.                         clr_eol();
  319.                         emdp->bigrect.top = (ypos + 1) * emdp->lineheight + emdp->voffset;
  320.                         clearrect(&emdp->bigrect);
  321.                         emdp->bigrect.top = emdp->voffset;
  322.                     }
  323.                     if (emdp->logerase || (ypos == 0 && xpos == 0)) {
  324.                         /* save the screen before it gets overwritten */
  325.                         if (!emdp->ibm_keymode)
  326.                             savescreen();
  327.                     }
  328.             
  329.                     /* blank out the screen map */
  330.                     c19_blank(charp, emdp->charrend - charp);
  331.                     break;
  332.                 }
  333.                 case 'K': {
  334.                     /* clear EOL */
  335.                     clr_eol();
  336.                     break;
  337.                 }
  338.                 case 'L': {
  339.                     /* insert line */
  340.                     ins_lin(ypos);
  341.                     charp -= xpos;
  342.                     xpos = 0;
  343.                     break;
  344.                 }
  345.                 case 'M': {
  346.                     /* delete line */
  347.                     del_lin(ypos);
  348.                     charp -= xpos;
  349.                     xpos = 0;
  350.                     break;
  351.                 }
  352.                 case 'N': {
  353.                     /* delete char */
  354.                     del_char();
  355.                     break;
  356.                 }
  357.                 case '@': {
  358.                     /* enter insert char mode */
  359.                     inserton = TRUE;
  360.                     showinsert();  
  361.                     break;
  362.                 }
  363.                 case 'O': {
  364.                     /* exit insert char mode */
  365.                     inserton = FALSE;
  366.                     clrinsert();  
  367.                     break;
  368.                 }
  369.                 case 'Y': {
  370.                     /* cursor calculation */
  371.                     mode = YCALC;
  372.                     continue;
  373.                 }
  374.                 case 'Z': {
  375.                     /* identify as VT52 */
  376.                     vt52response();
  377.                     break;
  378.                 }
  379.                 case '=': {
  380.                     /* enter alt keypad mode, vt52 compatibility */
  381.                     emdp->vt52altkeypad = TRUE;
  382.                     break;
  383.                 }
  384.                 case '>': {
  385.                     /* exit alt keypad mode, vt52 compatibility */
  386.                     emdp->vt52altkeypad = FALSE;
  387.                     break;
  388.                 }
  389.                 case '<': {
  390.                     if (emdp->termtype == TERM_VT100
  391.                         || keydp->termtype == TERM_VT102
  392.                         || keydp->termtype == TERM_VT220
  393.                     ) {
  394.                         /* we've been doing vt52 for vt100, return */
  395.                         mode = VT100MODE;
  396.                         emdp->em = vt100;
  397.                         emdp->emstr = vt100str;
  398.                         emend();    /* emprep will be called again */
  399.                         vt100str(strp, endp - strp);
  400.                         return(0);
  401.                     }
  402.                     break;
  403.                 }
  404.                 case 'b': {
  405.                     /* clear screen up to cursor position */
  406.                     Rect trect;
  407.                     
  408.                     if (emdp->selrectvis  || bkrd_act || emupdwait) {
  409.                         /* must redraw through upd */
  410.                         for (count = 0; count < ypos; count++)
  411.                             modflg |= modmask[count];
  412.                     }
  413.                     else {
  414.                         emdp->bigrect.bottom = ypos * emdp->lineheight + emdp->voffset;
  415.                         clearrect(&emdp->bigrect);
  416.                         emdp->bigrect.bottom = emdp->bottommarg;
  417.  
  418.                         trect.top = ypos * emdp->lineheight + emdp->voffset;
  419.                         trect.bottom = trect.top + emdp->lineheight;
  420.                         trect.left = emdp->hoffset;
  421.                         trect.right = xpos * fontwidth;
  422.                         clearrect(&trect);
  423.                     }
  424. #ifdef SAVEONERASE
  425.                     if (!emdp->ibm_keymode && emdp->logerase)
  426.                         saveline(&emdp->charr[0], charp - emdp->charr + 1);
  427.                         /* save the line if needed before it gets overwritten */
  428. #endif
  429.                     c19_blank(&emdp->charr[0], charp - emdp->charr + 1);
  430.                     break;
  431.                 }
  432.                 case 'l': {
  433.                     /* clear current line */
  434.                     Rect temprect;
  435.                     char * destp;
  436.  
  437.                     if (emdp->selrectvis  || bkrd_act || emupdwait) {
  438.                         /* must redraw through upd */
  439.                         modflg |= modmask[ypos];
  440.                     }
  441.                     else {
  442.                         temprect.top = ypos * emdp->lineheight + emdp->voffset;
  443.                         temprect.left = emdp->hoffset;
  444.                         temprect.bottom = temprect.top + emdp->lineheight;
  445.                         temprect.right = emdp->rightmarg;
  446.                         clearrect(&temprect);
  447.                     }
  448.                     destp = emdp->charr + ypos * linelength;
  449.                     if (!emdp->ibm_keymode)
  450.                         saveline(destp, linelength);
  451.  
  452.                     c19_blank(destp, linelength);
  453.                     break;
  454.                 }
  455.                 case 'o': {
  456.                     clrtocurs();
  457.                     break;
  458.                 }
  459.                 case 'p': {
  460.                 /* ordinarily produces inverse video */
  461. #ifdef INVEQALT
  462.                     /* start alt char set */
  463.                     attrib |= BOLD;
  464. #else
  465.                     /* reverse video */
  466.                     attrib |= REVERSE;
  467. #endif
  468. #ifdef FASTDRAW
  469.                     setascattr_ds(attrib, emdp->inselection);
  470. #endif
  471.                     break;
  472.                 }
  473.                 case 'q': {
  474.                     /* end alt char set */
  475.                     attrib = NORMFONT;
  476. #ifdef FASTDRAW
  477.                     setascattr_ds(attrib, emdp->inselection);
  478. #endif
  479.                     break;
  480.                 }
  481. #ifdef UNDERSTOOD
  482.                 /* TODO check out what this mode is supposed to do */
  483.                 case 't': {
  484.                     /* enter shift keypad mode */
  485.                     emdp->vt52shiftkeypad = TRUE;
  486.                     break;
  487.                 }
  488.                 case 'u': {
  489.                     /* exit shift keypad mode */
  490.                     emdp->vt52shiftkeypad = FALSE;
  491.                     break;
  492.                 }
  493. #endif
  494.                 case 'v': {
  495.                     /* wrap on */
  496.                     wrap_around = TRUE;
  497.                     break;
  498.                 }
  499.                 case 'w': {
  500.                     /* wrap off */
  501.                     wrap_around = FALSE;
  502.                     break;
  503.                 }
  504.                 case 'x': {
  505.                     /* set heath modes */
  506.                     mode = SETMODES;
  507.                     continue;
  508.                 }
  509.                 case 'y': {
  510.                     /* reset heath modes */
  511.                     mode = RESETMODES;
  512.                     continue;
  513.                 }
  514.                 case '+': {
  515.                     /* go into IBM keymode */
  516.                     if (!emdp->ibm_keymode) {
  517.                         emdp->ibm_keymode = TRUE;
  518.                         setibm_keymode(emdp->ibm_keymode);
  519.                     }
  520.                     break;
  521.                 }
  522.                 case '-': {
  523.                     /* exit IBM keymode */
  524.                     if (emdp->ibm_keymode) {
  525.                         emdp->ibm_keymode = FALSE;
  526.                         setibm_keymode(emdp->ibm_keymode);
  527.                     }
  528.                     break;
  529.                 }
  530.             }
  531.             mode = NORMMODE;
  532.         }
  533.         else if (mode == SETMODES) {
  534.             switch (thechar) {
  535.                 case '4': {
  536.                     showinsert();
  537.                     break;
  538.                 }
  539.             }
  540.             mode = NORMMODE;
  541.         }
  542.         else if (mode == RESETMODES) {
  543.             switch (thechar) {
  544.                 case '4': {
  545.                     clrinsert();
  546.                     break;
  547.                 }
  548.             }
  549.             mode = NORMMODE;
  550.         }
  551.         else if (mode == YCALC) {
  552.             emdp->argarr[0]  = thechar - ' ';
  553.             mode = XCALC;
  554.         }
  555.         else if (mode == XCALC) {
  556.             short ex;
  557.             short ey = emdp->argarr[0];
  558.             
  559.             ex = thechar - ' ';
  560.             mode = NORMMODE;
  561.             if (ey >= 0 && ey <= emdp->lastrow && ex >= 0 && ex <= lastcol) {
  562.                 ypos = ey;
  563.                 xpos = ex;
  564.                 charp = emdp->charr + ((ypos * linelength) + xpos);
  565.             }
  566.         }
  567.         else if (mode == CFTMODE) {
  568.             cft(thechar);
  569.         }
  570.         else if (mode == CFT2MODE) {
  571.             cft2(thechar);
  572.         }
  573.         else if (mode == C19FTMODE) {
  574.             c19ft(thechar);
  575.         }
  576.     }
  577.     newcursor();
  578.     emend();
  579. }
  580.  
  581.  
  582. /* reset the h19 emulator */
  583.  
  584. h19reset()
  585. {
  586.     GrafPtr oport;
  587.     
  588.     emreset();
  589.  
  590.     /* blank out the screen map */
  591.     c19_blankmap(&emdp->charr[0]);
  592.         
  593.     setcontext(emdp);                    /* update globals */
  594.  
  595.     if (emdp->emwindow) {
  596.         if (updatewait()) {
  597.             modflg = emdp->modflg = SCRALLMOD;
  598.                 /* update emdp since this routine may not be 
  599.                     called from screen_service */
  600.         }
  601.         else {
  602.             GetPort(&oport);
  603.             SetPort(emwindow);
  604.             
  605.             clearrect(&emdp->bigrect);
  606.         
  607.             clrflg = emdp->clrflg = SCRALLMOD;
  608.                 /* update emdp since this routine may not be 
  609.                     called from screen_service */
  610.  
  611.             emdp->curson = FALSE;
  612.             if (emdp == keydp)
  613.                 trackon = FALSE;
  614.             
  615.             if (emdp->selrectset)
  616.                 selinvert(emdp);
  617.             
  618.             SetPort(oport);
  619.         }
  620.     }
  621.     newcursor();
  622. }
  623.  
  624.  
  625. emreset()
  626. {
  627.     emdp->mode = NORMMODE;                            /* interpretation mode of emulator */
  628.  
  629. #ifdef VARVTSIZE
  630.     if (emdp->charr)
  631.         DisposPtr(emdp->charr);
  632.     if (emdp->tabset)
  633.         DisposPtr(emdp->tabset);
  634.         
  635.     emdp->charr = NewPtr((Size) (2 * emdp->linelength * emdp->linecount));
  636.     emdp->tabset = NewPtr((Size) emdp->linelength);
  637. #endif
  638.  
  639. #ifdef VARVTSIZE
  640.     emdp->lastcol = emdp->linelength - 1;
  641.     emdp->lastrow = emdp->linecount - 1;
  642.  
  643.     emdp->screensize = emdp->linelength * emdp->linecount;
  644.     emdp->size23 = emdp->screensize - emdp->linelength;
  645. #else
  646.     emdp->lastcol = LASTCOL;
  647.     emdp->lastrow = LASTROW;
  648.     emdp->linelength = LINELENGTH;
  649.     emdp->screensize = SCREENSIZE;
  650.  
  651.     emdp->size23 = SIZE23;
  652.     emdp->linecount = 24;
  653. #endif
  654.  
  655.     emdp->xpos = 0;
  656.     emdp->ypos = 0;
  657.     emdp->charp = emdp->charr;                        /* cursor loc for these arrays */
  658.     emdp->charrend = &emdp->charr[emdp->screensize];
  659.     emdp->atarr = emdp->charp + emdp->screensize;                    /* attributes on screen */
  660.     emdp->secondline = emdp->charp + emdp->linelength;
  661.     emdp->lastline = emdp->charp + emdp->size23;
  662.     emdp->scrolltop = TOPROW;
  663.     emdp->scrollbottom = emdp->lastrow;
  664.     
  665.     emdp->attrib = 0;
  666.     emdp->charset = 0;
  667.  
  668.     emdp->bigrect.top = emdp->voffset;
  669.     emdp->bigrect.left = emdp->hoffset;
  670.     emdp->bigrect.bottom = emdp->bottommarg;
  671.     emdp->bigrect.right = emdp->rightmarg;
  672. }
  673.  
  674.  
  675. /* respond to terminal type inquiry:  we are a vt52! */
  676.  
  677. vt52response()
  678. {
  679.     (*emdp->sendchar)(ESC);
  680.     (*emdp->sendchar)('/');
  681.     (*emdp->sendchar)('K');
  682.     (*emdp->putflush)();
  683. }
  684.  
  685.  
  686. /* blank out ccount char/attribs */
  687.  
  688. c19_blank(charp, ccount)
  689. register unsigned char * charp;
  690. register int ccount;
  691. {
  692.     register unsigned char * attp = charp + emdp->screensize;
  693.     
  694.     while (ccount--) {
  695.         *charp++ = ' ';
  696.         *attp++ = 0;
  697.     }
  698. }
  699.  
  700.  
  701. /* blank out an h19/vt100 screen */
  702.  
  703. c19_blankmap(charp) 
  704. register unsigned char * charp;
  705. {
  706.     register unsigned char * attp = charp + emdp->screensize;
  707.     register int ccount = emdp->screensize;
  708.     
  709.     while (ccount--) {
  710.         *charp++ = ' ';
  711.         *attp++ = 0;
  712.     }
  713. }
  714.  
  715.